#ifndef HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPSERVICE_H_
#define HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPSERVICE_H_

#include "CBaseNetHeader.h"
#include "mongoose.h"
#include <QMutex>

BASENET_BEGIN_NAMESPACE

// 连接信息
#define HTTP_SERVICE_CONNECTION MAP<unsigned long, struct mg_connection *>

/**
 * url 运行函数，如果返回ture,地址不会保存连接信息，回调内必需回复http内容
 *
 * @note
 * @return -
 */
typedef bool (*httpUrlhander)(struct mg_connection *,struct mg_http_message *hm, void *fn_data);
// url处理结构体
struct urlHandler
{
	string url;
	httpUrlhander handler;
	void * data;
	urlHandler()
	{
		url="";
		handler= NULL;
		data = NULL;
	}
};

// 处理信息
#define HTTP_SERVICE_HANDLER MAP<string, struct urlHandler>

// 文件接收
typedef struct _tRecvFileInfo{
	// 文件句柄
	FILE				*fp;
	// 要接收的文件总大小
	long long 	fileTotalSize;
	// 已接收的文件的文件总大小
	long long 	fileCurrentSize;
	// 文件保存路径
	string		saveFilePath;
	string		contentType;

	_tRecvFileInfo()
	{
		fp = nullptr;
		fileTotalSize = 0;
		fileCurrentSize = 0;
		saveFilePath = "";
		contentType = "";
	}

}T_RecvFileInfo;


class BASENET_API CHttpService : public QThread{

    Q_OBJECT
public:

	/**
	 * 构造函数
	 *
	 * @note
	 * @return -
	 */
    CHttpService(string url, QObject *p = nullptr);

	CHttpService(string url, long IOsize, long mgRecvBufSize);

	CHttpService(string url,struct mg_tls_opts *opts);

	CHttpService(string url,struct mg_tls_opts *opts, long IOsize, long mgRecvBufSize);

	/**
	 * 析构函数
	 *
	 * @note
	 * @return -
	 */
	~CHttpService();

public:

	///////////////////////////// 外部接口 //////////////////////////////////
	/**
	 * 启动HTTP服务器
	 *
	 * @note
	 * @return -
	 */
	bool start(string url = "", struct mg_tls_opts *opts = NULL);

	/**
	 * 启动HTTP服务器
	 *
	 * @note
	 * @return -
	 */
	void stop();

	/**
	*发送数据
	*
	* @note
	* @param[in] id 连接唯一ID
	* @param[in] head 发送头
	* @param[in] bodyData 发送body
	* @param[in] path 展示路径
	* @param[in] hm 请求信息
	*
	* @return - 发送状态
	*/
	bool sendData(unsigned long id, MAP_PARAMS head, string bodyData);
	bool sendData(unsigned long id,string heads, string bodyData);
	bool sendData(unsigned long id,struct mg_http_serve_opts sopts, struct mg_http_message *hm);

	/**
	 * 注册处理函数
	 *@param[in] url 路径（支持匹配）
	 *@param[in] back 处理函数
	 *@param[in] 回调指针
	 * @note
	 * @return -
	 */
	bool registerHandler(string url,httpUrlhander back,void *data);

	/**
	 * 反注册回调函数
	 * @return -
	 */
	void unRegisterHandler(string url);

	// 注册web处理函数
	void registerWebHandler(std::function<void(struct mg_connection *,struct mg_http_message *)> &&back){m_webBack = back;}

	// 设置文件上传完成函数
	void setuploadFileHandler(string uploadUrl, string saveDir, std::function<void(struct mg_connection *,string)> &&back){m_uploadFileBack = back;m_uploadFileUrl = uploadUrl;m_uploadFileSaveDir = saveDir;}



public:
	/**
	 * http pool回调
	 *
	 * @note
	 * @return -
	 */
	void __httpServiceCB(struct mg_connection *c, int ev, void *ev_data);

private:
	// 线程实现
	virtual void run();

	/**
	 * 保存连接信息
	 *
	 * @note
	 * @return -
	 */
	void saveConnection(struct mg_connection *c);

	/**
	 * 删除连接信息
	 *
	 * @note
	 * @return -
	 */
	void delConnection(struct mg_connection *c);

	/**
	 * 运行url
	 *
	 * @note
	 * @return -
	 */
	bool runHandler(struct mg_connection *c, struct mg_http_message *hm);

	/**
	 * 块数据处理函数
	 *
	 * @note
	 * @return -
	 */
	bool chunkHandler(struct mg_connection *c, struct mg_http_message *hm);

	/**
	 * 写入文件
	 *
	 * @note
	 * @return -
	 */
	void writeFile(const char *buf, long long len);

private:
	// 连接管理器
	struct mg_mgr m_sMgr;

private:
	// 运行状态
	bool m_bRunStatus;
	// 监听地址
	string m_sUrl;
	// HTTPS证书信息
	struct mg_tls_opts m_sOpts;
	// 互斥锁
    QMutex     m_Mutex;
	// 保存连接信息
	HTTP_SERVICE_CONNECTION m_mHttpConnectInfo;
	// 保存处理函数
	HTTP_SERVICE_HANDLER m_mHttpHandler;
	// 文件上传url
	string				m_uploadFileUrl;
	// 文件上传保存路径
	string 				m_uploadFileSaveDir;
	// 文件保存路径
	string				m_saveFilePath;
	// 文件接收map，解决并发问题
	MAP<unsigned long, T_RecvFileInfo> m_recvFileMap;
	// web回调
	std::function<void(struct mg_connection *,struct mg_http_message *)> m_webBack;
	// 文件上传回调
	std::function<void(struct mg_connection *,string)> m_uploadFileBack;

};
BASENET_END_NAMESPACE

#endif // HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPSERVICE_H_
